import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class Solution210 {

    List<Integer>[] adjacencyTable;

    short[] visit;

    int[] res;

    int index;

    boolean isRing;

    private void init(int numCourses, int[][] prerequisites){
        visit = new short[numCourses];
        res = new int[numCourses];
        index = numCourses - 1;
        isRing = false;
        adjacencyTable = new List[numCourses];

        for(int i = 0; i < numCourses; i++){
            adjacencyTable[i] = new ArrayList<>();
        }
        for(int[] prerequisite : prerequisites){
            adjacencyTable[prerequisite[1]].add(prerequisite[0]);
        }
    }

    private void dfs(int loc){
        if(visit[loc] == 1) {isRing = true; return; }
        if(visit[loc] == 2) { return; }
        visit[loc] = 1;
        List<Integer> adj = adjacencyTable[loc];
        for(Integer nextLoc : adj){
            dfs(nextLoc);
            if(isRing){return;}
        }
        visit[loc] = 2;
        res[index--] = loc;
    }

    public int[] findOrder(int numCourses, int[][] prerequisites) {
        init(numCourses, prerequisites);
        for(int i = 0; i < numCourses && !isRing; i++){
            if(visit[i] != 2){
                dfs(i);
            }
        }
        if(isRing){
            return new int[0];
        }
        return res;
    }

    public static void main(String[] args) {
        Solution210 s = new Solution210();
        s.findOrder(4, new int[][]{new int[]{1,0}, new int[]{2,0}, new int[]{3,1}, new int[]{3,2}});
    }
}
